package com.atguigu.jinx.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.atguigu.jinx.entity.dto.RechargeOrder;
import com.atguigu.jinx.entity.dto.RechargeRequest;
import com.atguigu.jinx.entity.dto.UserBalance;
import com.atguigu.jinx.entity.vo.PayAsyncVo;
import com.atguigu.jinx.enums.ProcessStatus;
import com.atguigu.jinx.enums.alipay.AlipayTradeStatus;
import com.atguigu.jinx.exception.BusinessException;
import com.atguigu.jinx.mapper.RechargeOrderMapper;
import com.atguigu.jinx.mapper.RechargeRequestMapper;
import com.atguigu.jinx.service.IRechargeOrderService;
import com.atguigu.jinx.service.IRechargeRequestService;
import com.atguigu.jinx.service.IUserBalanceService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author steve
 * @since 2025-08-07
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class RechargeOrderServiceImpl extends ServiceImpl<RechargeOrderMapper, RechargeOrder> implements IRechargeOrderService {
    /**
     *
     */
    private final AlipayTemplate alipayTemplate;

    private final RechargeRequestMapper rechargeRequestMapper;

    private final Gson gson = new GsonBuilder().create();

    private final IUserBalanceService userBalanceService;


    @Override
    public String dealNotify(PayAsyncVo payAsyncVo, HttpServletResponse response) throws AlipayApiException {
        Map<String, String> map = gson.fromJson(gson.toJson(payAsyncVo), new TypeToken<Map<String, String>>() {
        }.getType());

        boolean signVerified = AlipaySignature.rsaCheckV1(map,
                alipayTemplate.getAlipay_public_key(),
                alipayTemplate.getCharset(),
                alipayTemplate.getSign_type());

        if (signVerified) {
            log.info("接收到异步通知回调验签成功,拿到的支付宝回调数据==>[{}]", payAsyncVo);
            sendResultToCustomerSys(payAsyncVo);
            response.setStatus(HttpStatus.SC_OK);
            return "success";
        } else {
            log.error("验签失败,[{}]", payAsyncVo);
            return "false";
        }
    }


    /**
     * 更新订单状态
     *
     * @param payAsyncVo 回调结果
     */
    @Transactional(rollbackFor = Exception.class)
    public void sendResultToCustomerSys(PayAsyncVo payAsyncVo) {
        String outTradeNo = payAsyncVo.getOut_trade_no();
        RechargeRequest request = rechargeRequestMapper.selectOne(new LambdaQueryWrapper<RechargeRequest>()
                .eq(RechargeRequest::getOutOrderNo, outTradeNo));

        // 首先确认订单能否被查到
        if (request == null) {
            log.error("支付宝回调未查询到订单信息=====>回调结果:{},订单号:{}", payAsyncVo, outTradeNo);
            throw new BusinessException("支付宝回调未查询到订单信息");
        }

        // 检查amount是否一致
        if (!Objects.equals(request.getAmount().toString(), payAsyncVo.getTotal_amount())) {
            log.error("支付宝回调金额不一致=====>回调结果:{},订单号:{}", payAsyncVo, outTradeNo);
            return;
        }

        // 确定订单状态
        String tradeStatus = payAsyncVo.getTrade_status();
        AlipayTradeStatus alipayTradeStatus = AlipayTradeStatus.fromCode(tradeStatus);

        switch (Objects.requireNonNull(alipayTradeStatus)) {
            case TRADE_CLOSED -> {
                log.info("支付宝回调:=====>{},订单号:{}", alipayTradeStatus.getDescription(), outTradeNo);
                request.setStatus(ProcessStatus.FAILED.getCode());
                rechargeRequestMapper.updateById(request);
            }
            
            case TRADE_SUCCESS, TRADE_FINISHED -> {
                log.info("支付宝回调:=====>{},订单号:{}", alipayTradeStatus.getDescription(), outTradeNo);
                successAddBalance(request);
            }

            case WAIT_BUYER_PAY -> {
                log.info("支付宝回调:=====>{},订单号:{}", alipayTradeStatus.getDescription(), outTradeNo);
                // 调用查单对象修改对象的状态
                IRechargeRequestService proxy = (IRechargeRequestService) AopContext.currentProxy();
                proxy.changeRechargeOrderSyncStatusFromAlipay(outTradeNo);
            }

        }

    }

    /**
     * 添加余额
     *
     * @param request 请求
     */
    private void successAddBalance(RechargeRequest request) {
        LambdaUpdateWrapper<UserBalance> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(UserBalance::getUserId, request.getUserId());
        updateWrapper.setSql("balance = balance + " + request.getAmount());
        userBalanceService.update(updateWrapper);
        request.setStatus(ProcessStatus.SUCCESS.getCode());
        rechargeRequestMapper.updateById(request);
    }
}
